package cn.abcsys.devops.application.service;/**
 * Copyright (2017, ) Institute of Software, Chinese Academy of Sciences
 */

import cn.abcsys.devops.application.dao.*;
import cn.abcsys.devops.application.model.*;
import cn.abcsys.devops.application.util.Policy;
import cn.abcsys.devops.application.util.UsefulTools;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.Inet4Address;
import java.util.*;

/**
 * @author xuyuanjia2017@otcaix.iscsa.ac.cn
 * @date 2017/6/25 0025
 * say sth.
 */
@Service("dbService")
public class DbService {

    @Resource(name="applicationCoreMapper")
    private ApplicationCoreMapper acm;

    @Resource(name="applicationInstanceRelationMapper")
    private ApplicationInstanceRelationMapper airm;

    @Resource(name="configBasicMapper")
    private ConfigBasicMapper cbm;

    @Resource(name="configEnvsMapper")
    private ConfigEnvsMapper cem;

    @Resource(name="configVolumesMapper")
    private ConfigVolumesMapper cvm;

    @Resource(name="configPortsMapper")
    private ConfigPortsMapper cpm;

    @Resource(name="configCoreMapper")
    private ConfigCoreMapper ccm;

    @Resource(name="instanceImageMapper")
    private InstanceImageMapper iim;

    public ApplicationCoreMapper getAcm() {
        return acm;
    }

    public void setAcm(ApplicationCoreMapper acm) {
        this.acm = acm;
    }

    public ApplicationInstanceRelationMapper getAirm() {
        return airm;
    }

    public void setAirm(ApplicationInstanceRelationMapper airm) {
        this.airm = airm;
    }

    public ConfigBasicMapper getCbm() {
        return cbm;
    }

    public void setCbm(ConfigBasicMapper cbm) {
        this.cbm = cbm;
    }

    public ConfigEnvsMapper getCem() {
        return cem;
    }

    public void setCem(ConfigEnvsMapper cem) {
        this.cem = cem;
    }

    public ConfigVolumesMapper getCvm() {
        return cvm;
    }

    public void setCvm(ConfigVolumesMapper cvm) {
        this.cvm = cvm;
    }

    public ConfigPortsMapper getCpm() {
        return cpm;
    }

    public void setCpm(ConfigPortsMapper cpm) {
        this.cpm = cpm;
    }

    public ConfigCoreMapper getCcm() {
        return ccm;
    }

    public void setCcm(ConfigCoreMapper ccm) {
        this.ccm = ccm;
    }

    public ParamsApplication setApplicationCore(ParamsApplication paramsApplication){
        paramsApplication.applicationCore.setApplicationCoreRename(paramsApplication.applicationCore.getApplicationCoreName()
                +"-"
                +paramsApplication.applicationCore.getApplicationCoreType()
                +"-"
                + UsefulTools.getSimpleCurrentDateTIme());
        paramsApplication.applicationCore.setApplicationCoreCreateDatetime(new Date());
        paramsApplication.applicationCore.setApplicationRuntimeId(paramsApplication.envId);
        paramsApplication.applicationCore.setApplicationCoreUpdateDatetime(new Date());
        return paramsApplication;
    }

    public ParamsApplication setAllConfig(ParamsApplication paramsApplication){
        if(paramsApplication.configEnvsListString !=null){
            List<ConfigEnvs> ceList = new ArrayList<>();
            String[] eachKv = paramsApplication.configEnvsListString.split(";");
            for(String kv:eachKv){
                String[] detail = kv.split(":");
                if(detail.length == 2){
                    ConfigEnvs ce = new ConfigEnvs();
                    ce.setConfigEnvsName(detail[0]);
                    ce.setConfigEnvsValue(detail[1]);
                    ceList.add(ce);
                }
            }
            paramsApplication.configEnvsList = ceList;
        }
        if(paramsApplication.configPortsListString !=null){
            List<ConfigPorts> cpList = new ArrayList<>();
            String[] eachPort = paramsApplication.configPortsListString.split(";");
            for(String port : eachPort){
                if(port.length()>=4){
                    ConfigPorts cp = new ConfigPorts();
                    cp.setConfigPortsPort(Integer.valueOf(port));
                    cpList.add(cp);
                }
            }
            paramsApplication.configPortsList = cpList;
        }
        if(paramsApplication.configVolumesListString !=null){
            List<ConfigVolumes> cvList = new ArrayList<>();
            String[] eachVolume = paramsApplication.configVolumesListString.split(";");
            for(String vo : eachVolume){
                String[] detail = vo.split(":");
                if(detail.length == 4){
                    //local:local-name:/root:NFSFileSys
                    ConfigVolumes cv = new ConfigVolumes();
                    cv.setConfigVolumesType(detail[0]);
                    cv.setConfigVolumesName(detail[1]);
                    cv.setConfigVolumesPath(detail[2]);
                    cv.setConfigVolumesMountPath(detail[3]);
                    cvList.add(cv);
                }
            }
            paramsApplication.configVolumesList = cvList;
        }
        return paramsApplication;
    }

    public Boolean checkSptringSpliterMatch(String list1,String list2){
        System.out.println("list1"+list1);
        System.out.println("list2"+list2);
        if(list1 == null && list2 != null || list1!=null && list2 ==null){
            return false;
        }
        else if(list1 == null && list2 == null){
            return true;
        }
        else if(list1.length() == 0 && list2.length() == 0){
            return true;
        }
        else if(list1.length() == 0 && list2.length() > 0 || list1.length() > 0 && list2.length() == 0){
            return false;
        }
        else{
            String[] eachList1 = list1.split(";");
            String[] eachList2 = list2.split(";");
            System.out.println(eachList1.length);
            System.out.println(eachList2.length);
            if(eachList1.length != eachList2.length){
                return false;
            }
            else{
                for(String temp1 :eachList1){
                    Boolean tempTag = false;
                    for(String temp2:eachList2){
                        if(temp1.equals(temp2)){
                            tempTag = true;
                            break;
                        }
                    }
                    if(tempTag == false){
                        return false;
                    }
                }
                return true;
            }
        }
    }

    public Boolean compare2ConfigVersion(ParamsApplication current,ParamsApplication old){
        if(!current.configBasic.getConfigBasicCpu().equals(old.configBasic.getConfigBasicCpu())){
            return false;
        }
        if(!current.configBasic.getConfigBasicMemory().equals(old.configBasic.getConfigBasicMemory())){
            return false;
        }
        if(!current.configBasic.getConfigBasicNetwork().equals(old.configBasic.getConfigBasicNetwork())){
            return false;
        }
        Boolean volumeCheck = this.checkSptringSpliterMatch(current.configVolumesListString,old.configVolumesListString);
        Boolean envCheck = this.checkSptringSpliterMatch(current.configEnvsListString,old.configEnvsListString);
        Boolean portsCheck = this.checkSptringSpliterMatch(current.configPortsListString,old.configPortsListString);
        return volumeCheck&envCheck&portsCheck;
    }

    public ParamsApplication compareAndSetAllConfig(ParamsApplication paramsApplication){
        ConfigCore cc = this.ccm.selectByPrimaryKey(paramsApplication.cc.getConfigCoreId());
        ParamsApplication oldPa = this.setParamsApplicationsConfigInfo(cc);
        if(this.compare2ConfigVersion(oldPa,paramsApplication)){
            paramsApplication.cc = cc;
        }
        else{
            paramsApplication.cc = null;
        }
        return paramsApplication;
    }

    public Map<String,Object> saveRawApplicationCoreInfo(ParamsApplication paramsApplication){
        Map<String,Object> resMap = new HashMap<>();
        paramsApplication.applicationCore.setApplicationCoreImagesCounts(0);
        acm.insertSelective(paramsApplication.applicationCore);
        if(paramsApplication.applicationCore.getApplicationCoreId() !=null){
            resMap.put("applicationCoreId",paramsApplication.applicationCore.getApplicationCoreId());
            resMap.put("applicationCoreName",paramsApplication.applicationCore.getApplicationCoreName());
            resMap.put("applicationCoreRename",paramsApplication.applicationCore.getApplicationCoreRename());
            resMap.put("success",true);
            resMap.put("message","保存了应用的基础信息！");
        }
        else{
            resMap.put("success",false);
            resMap.put("message","服务器异常！");
        }
        return resMap;
    }

    public StringBuilder insertAListOfApplicationInstanceRelation(ParamsApplication paramsApplication,Integer currentConfigId){
        //air.setInstanceCoreId();
        StringBuilder sb = new StringBuilder();
        this.insertOneImage(paramsApplication);
        for(int i=0;i<paramsApplication.instanceReplica;i++){
            ApplicationInstanceRelation air = new ApplicationInstanceRelation();
            air.setApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
            air.setConfigCoreId(currentConfigId);
            air.setImageId(paramsApplication.instanceImage.getConfigImageId());
            airm.insertSelective(air);
            sb.append("applicationInstanceRelationId"+i+":"+air.getApplicationInstanceRelationId()+";");
        }
        return sb;
    }

    public InstanceImage insertOneImage(ParamsApplication paramsApplication){
        iim.insertSelective(paramsApplication.instanceImage);
        return paramsApplication.instanceImage;
    }

    //config and instance.
    public Map<String,Object> saveOrDoNothingApplicationAllInfo(ParamsApplication paramsApplication){
        if(paramsApplication.applicationCore.getApplicationCoreId() == null)
            acm.insertSelective(paramsApplication.applicationCore);
        this.updateApplicationImageCount(paramsApplication);
        //System.out.println("创建应用，其ID为："+paramsApplication.applicationCore.getApplicationCoreId());
        int currentConfigId = -1;
        if(paramsApplication.cc ==null||paramsApplication.cc.getConfigCoreId() == null){
            //System.out.println("good");
            currentConfigId = this.saveApplicationConfigInfo(paramsApplication);
        }
        else{
            currentConfigId = paramsApplication.cc.getConfigCoreId();
        }
        StringBuilder sb = this.insertAListOfApplicationInstanceRelation(paramsApplication,currentConfigId);
        if(paramsApplication.instanceReplica>=1){
            return new HashMap<String,Object>(){
                {
                    put("applicationInstanceRelation",sb.toString());
                    put("applicationCoreId",paramsApplication.applicationCore.getApplicationCoreId());
                    put("applicationRename",paramsApplication.applicationCore.getApplicationCoreRename());
                    put("applicationName",paramsApplication.applicationCore.getApplicationCoreName());
                    put("success",true);
                    put("message","保存了应用的配置信息！");
                }
            };
        }
        return new HashMap<String,Object>(){
            {
                put("success",false);
                put("message","参数输入无效，请重新输入！");
            }
        };

    }

    public Integer saveApplicationConfigInfo(ParamsApplication paramsApplication){
        StringBuilder configEnvsIds = new StringBuilder("");
        StringBuilder configPortsIds = new StringBuilder("");
        StringBuilder configVolumesIds = new StringBuilder("");
        StringBuilder configBasicId = new StringBuilder("");
        if(paramsApplication.configEnvsList != null){
            for(ConfigEnvs ce : paramsApplication.configEnvsList){
                cem.insertSelective(ce);
                configEnvsIds.append(ce.getConfigEnvsSelfId()+";");
            }
        }
        if(paramsApplication.configPortsList != null){
            for(ConfigPorts cp : paramsApplication.configPortsList){
                cpm.insertSelective(cp);
                configPortsIds.append(cp.getConfigPortsSelfId()+";");
            }
        }
        if(paramsApplication.configVolumesList != null){
            for(ConfigVolumes cv:paramsApplication.configVolumesList){
                cvm.insertSelective(cv);
                configVolumesIds.append(cv.getConfigVolumesSelfId()+";");
            }
        }
        if(paramsApplication.configBasic != null){
            paramsApplication.configBasic.setConfigBasicSelfStatus("current");
            cbm.insertSelective(paramsApplication.configBasic);
            configBasicId.append(paramsApplication.configBasic.getConfigBasicSelfId()+";");
        }
        //ApplicationInstanceRelation air = new ApplicationInstanceRelation();
        ConfigCore cc = new ConfigCore();
        cc.setConfigBasicId(configBasicId.toString());
        cc.setConfigEnvsIds(configEnvsIds.toString());
        cc.setConfigPortsIds(configPortsIds.toString());
        cc.setConfigVolumesIds(configVolumesIds.toString());
        System.out.println(paramsApplication.applicationCore.getApplicationCoreId());
        cc.setApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        ccm.insertSelective(cc);

        ApplicationCore ac = acm.selectByPrimaryKey(paramsApplication.applicationCore.getApplicationCoreId());
        ac.setApplicationCoreUpdateDatetime(new Date());
        acm.updateByPrimaryKeySelective(ac);

        return cc.getConfigCoreId();
    }

    public List<ParamsApplication> getAllInfoByApplicationInstanceRelationIds(String ids){
        List<ParamsApplication> paList = new ArrayList<>();
        String[] eachId = ids.split(";");
        for(String temp:eachId){
            String[] kv = temp.split(":");
            if(kv.length == 2){
                Integer applicationInstanceRelationId = Integer.valueOf(kv[1]);
                ParamsApplication pa = this.getSingleInfoByapplicationInstanceRelationId(applicationInstanceRelationId);
                paList.add(pa);
            }
        }
        return paList;
    }

    public Map<String,Object> getApplicationConfigVersion(Integer applicationCoreId){
        List<Map<String,Object>> versions = new ArrayList<>();
        List<ConfigCore> ccList = ccm.selectByApplicationCoreId(applicationCoreId);
        for(int i=0;i<ccList.size();i++){
            Map<String,Object> tempMap = new HashMap<>();
            tempMap.put("name", ccList.get(i).getConfigCoreId());
            tempMap.put("value", ccList.get(i).getConfigCoreId());
            versions.add(tempMap);
        }
        return new HashMap<String,Object>(){
            {
                put("rows",versions);
                put("success",true);
            }
        }
        ;
    }

    public int updateInstanceCoreId(ApplicationInstanceRelation air,Integer instanceCoreId){
        air.setInstanceCoreId(instanceCoreId);
        air.setApplicationInstanceCurrentStatus("created");
        int insertStatus = airm.updateByPrimaryKeySelective(air);

        ApplicationCore ac = acm.selectByPrimaryKey(air.getApplicationCoreId());
        ac.setApplicationCoreUpdateDatetime(new Date());
        acm.updateByPrimaryKeySelective(ac);
        return insertStatus;
    }

    public ParamsApplication getConfigInfoByConfigCoreId(Integer configCoreId){
        ConfigCore cc = ccm.selectByPrimaryKey(configCoreId);
        return this.setParamsApplicationsConfigInfo(cc);
    }

    public ParamsApplication getSingleInfoByapplicationInstanceRelationId(Integer applicationInstanceRelationId){
        ApplicationInstanceRelation air = airm.selectByPrimaryKey(applicationInstanceRelationId);
        //&& air.getInstanceCoreId() == null
        if(air.getApplicationCoreId() !=null && air.getConfigCoreId() !=null){
            ConfigCore cc = ccm.selectByPrimaryKey(air.getConfigCoreId());
            ParamsApplication pa = this.setParamsApplicationsConfigInfo(cc);
            pa.instanceImage = iim.selectByPrimaryKey(air.getImageId());
            //System.out.println(pa.instanceImage.getConfigImageName());
            //System.out.println(pa.instanceImage.getConfigImageTag());
            pa.air = air;
            return pa;
        }
        return null;
    }

    private String configVolumesList2String(List<ConfigVolumes> cvList){
        StringBuilder sb = new StringBuilder("");
        //local:local-name:/root:NFSFileSys
        for(ConfigVolumes cv :cvList){
            sb.append(cv.getConfigVolumesType()+":"+cv.getConfigVolumesName()+":"+cv.getConfigVolumesPath()+":"+cv.getConfigVolumesMountPath()+";");
        }
        return sb.toString();
    }

    private String configPorts2String(List<ConfigPorts> cpList){
        StringBuilder sb = new StringBuilder("");
        for(ConfigPorts cp: cpList){
            sb.append(cp.getConfigPortsPort()+";");
        }
        return sb.toString();
    }

    private String configEnvs2String(List<ConfigEnvs> ceList){
        StringBuilder sb = new StringBuilder("");
        for(ConfigEnvs ce : ceList){
            sb.append(ce.getConfigEnvsName()+":"+ce.getConfigEnvsValue()+";");
        }
        return sb.toString();
    }

    public ParamsApplication setParamsApplicationsConfigInfo(ConfigCore cc){
        ParamsApplication pa = new ParamsApplication();
        if(cc.getConfigVolumesIds() !=null){
            pa.configVolumesList = this.getCvListFromConfigVolumesIds(this.convertIdsString(cc.getConfigVolumesIds()));
            pa.configVolumesListString = this.configVolumesList2String(pa.configVolumesList);
        }
        if(cc.getConfigPortsIds() !=null){
            pa.configPortsList = this.getCpListFromConfigPortsIds(this.convertIdsString(cc.getConfigPortsIds()));
            pa.configPortsListString = this.configPorts2String(pa.configPortsList);
        }
        if(cc.getConfigBasicId() !=null){
            pa.configBasic = this.getCbFromConfigBasicId(this.convertIdsString(cc.getConfigBasicId()));
        }
        if(cc.getConfigEnvsIds() !=null){
            pa.configEnvsList = this.getCeListFromConfigEnvsIds(this.convertIdsString(cc.getConfigEnvsIds()));
            pa.configEnvsListString = this.configEnvs2String(pa.configEnvsList);
        }
        pa.applicationCore = acm.selectByPrimaryKey(cc.getApplicationCoreId());
        return pa;
    }
    //null pointer exception
    public List<Integer> convertIdsString(String ids){
        String[] id = ids.split(";");
        List<Integer> res = new ArrayList<>();
        for(String temp : id){
            if(temp.length() >=1)
                res.add(Integer.valueOf(temp));
        }
        return res;
    }

    public List<ConfigEnvs> getCeListFromConfigEnvsIds(List<Integer> res){
        //List<Integer> res = this.convertIdsString(ids);
        List<ConfigEnvs> ceList = new ArrayList<>(res.size());
        for(int i=0;i<res.size();i++){
            ceList.add(cem.selectByPrimaryKey(res.get(i)));
        }
        return ceList;
    }

    public List<ConfigPorts> getCpListFromConfigPortsIds(List<Integer> res){
        List<ConfigPorts> cpList = new ArrayList<>(res.size());
        for(int i=0;i<res.size();i++){
            cpList.add(cpm.selectByPrimaryKey(res.get(i)));
        }
        return cpList;
    }

    public List<ConfigVolumes> getCvListFromConfigVolumesIds(List<Integer> res){
        List<ConfigVolumes> cvList = new ArrayList<>(res.size());
        for(int i=0;i<res.size();i++){
            cvList.add(cvm.selectByPrimaryKey(res.get(i)));
        }
        return cvList;
    }

    public ConfigBasic getCbFromConfigBasicId(List<Integer> res){
        if(res.size() == 1){
            return cbm.selectByPrimaryKey(res.get(0));
        }
        return null;
    }

    public Map<String,Object> checkApplicationNameByRuntime(ParamsApplication paramsApplication){
        Map<String,Object> resMap = new HashMap<>();
        List<ApplicationCore> ac = acm.selectByRuntimeAndApplicationName(paramsApplication.applicationCore);
        if(ac == null  || ac != null && ac.size() == 0){
            resMap.put("exist",true);
            resMap.put("message","实例名合法！");
            resMap.put("success",true);
        }
        else{
            resMap.put("exist",false);
            resMap.put("message","当前环境下已经有重名的实例！");
            resMap.put("success",false);
        }
        return resMap;
    }

    private List<ApplicationInstanceRelation> filterAirListByImageNameTag(List<ApplicationInstanceRelation> airList,ParamsApplication paramsApplication){
        List<ApplicationInstanceRelation> resList =  new ArrayList<ApplicationInstanceRelation>();
        for(ApplicationInstanceRelation air : airList){
            //System.out.println("relation ID:"+air.getApplicationInstanceRelationId());
            ParamsApplication pa = this.getSingleInfoByapplicationInstanceRelationId(air.getApplicationInstanceRelationId());
            String name_tag = pa.instanceImage.getConfigImageName()+":"+pa.instanceImage.getConfigImageTag();
            //System.out.println(name_tag);
            //System.out.println(paramsApplication.getImageNameTag());
            if(name_tag.equals(paramsApplication.getImageNameTag())){
                resList.add(air);
            }
        }
        return resList;
    }

    public Integer resetInstanceReplica(Integer policyIndex,ParamsApplication paramsApplication){
        List<ApplicationInstanceRelation> airList = airm.selectByApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        airList = this.filterAirListByImageNameTag(airList,paramsApplication);
        if(Policy.DILATION.ordinal() ==  policyIndex ){
            return airList.size()+paramsApplication.instanceCount;
        }
        else if(Policy.SHRINKAGE.ordinal() ==  policyIndex){
            return airList.size()-paramsApplication.instanceCount;
        }
        return null;
    }

    public List<ApplicationInstanceRelation> checkPolicyCorrectness(Integer policyIndex,ParamsApplication paramsApplication){
        List<ApplicationInstanceRelation> airList = airm.selectByApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        System.out.println("currentAll:"+airList.size());
        airList = this.filterAirListByImageNameTag(airList,paramsApplication);
        System.out.println("currentAfter"+airList.size());
        if(airList == null || airList !=null && airList.size() == 0){
            return new ArrayList<ApplicationInstanceRelation>();
        }
        if(Policy.DILATION.ordinal() ==  policyIndex && airList.size()<paramsApplication.instanceReplica && paramsApplication.instanceReplica>=1){
            List<ApplicationInstanceRelation> neededList = new ArrayList<ApplicationInstanceRelation>();
            int count = paramsApplication.instanceReplica - airList.size();
            for(int i=0;i<count;i++){
                ApplicationInstanceRelation air = new ApplicationInstanceRelation();
                air.setConfigCoreId(airList.get(0).getConfigCoreId());
                air.setApplicationCoreId(airList.get(0).getApplicationCoreId());
                //SB
                air.setImageId(airList.get(0).getImageId());
                airm.insertSelective(air);
                neededList.add(air);
            }
            return neededList;
        }
        else if(Policy.SHRINKAGE.ordinal() ==  policyIndex && airList.size() > paramsApplication.instanceReplica && paramsApplication.instanceReplica>=0){
            int count = airList.size() - paramsApplication.instanceReplica;
            System.out.println(count);
            System.out.println(airList.subList(0,count-1).size());
            return airList.subList(0,count);
        }
        return new ArrayList<ApplicationInstanceRelation>();
    }

    public List<ParamsApplication>  airList2paList(Integer policyIndex,ParamsApplication paramsApplication){
        List<ApplicationInstanceRelation> airList = this.checkPolicyCorrectness(policyIndex,paramsApplication);
        List<ParamsApplication> paList = new ArrayList<ParamsApplication>();
        for(ApplicationInstanceRelation air : airList){
            //System.out.println("getApplicationInstanceRelationId:"+air.getApplicationInstanceRelationId());
            paList.add(this.getSingleInfoByapplicationInstanceRelationId(air.getApplicationInstanceRelationId()));
        }
        return paList;
    }

    public void setApplicationInstanceRelationInvalid(ParamsApplication pa){
        ApplicationInstanceRelation air = pa.air;
        air.setApplicationInstanceCurrentStatus("invalid");
        airm.updateByPrimaryKeySelective(air);
    }

    public int countNetworks(List<ApplicationInstanceRelation> runningList){
        Set<String> networks = new HashSet<String>();
        for(ApplicationInstanceRelation r : runningList){
            ConfigCore cc = ccm.selectByPrimaryKey(r.getConfigCoreId());
            ConfigBasic cb = this.getCbFromConfigBasicId(this.convertIdsString(cc.getConfigBasicId()));
            if(cb !=null && cb.getConfigBasicNetwork() !=null){
                networks.add( cb.getConfigBasicNetwork());
            }
        }
        return networks.size();
    }

    public int countImageVersions(List<ApplicationInstanceRelation> runningList){
        Set<Integer> imageVersions = new HashSet<Integer>();
        for(ApplicationInstanceRelation r : runningList){
            imageVersions.add(r.getImageId());
        }
        return imageVersions.size();
    }

    public Map<String,Object> getApplicationDetails(ParamsApplication paramsApplication){
        Map<String,Object> resMap = new HashMap<String,Object>();

        List<ApplicationInstanceRelation> airList = airm.selectByApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        resMap.put("versionCounts",this.countImageVersions(airList));

        List<ApplicationInstanceRelation> runningList = airm.selectByApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        int currentAllCounts = airm.selectCountByApplicationCoreIdAndStatus(paramsApplication.applicationCore.getApplicationCoreId(),null);
        resMap.put("runningCounts",runningList.size());

        resMap.put("notRunningCounts",currentAllCounts - runningList.size());
        resMap.put("networkCounts",this.countNetworks(airList));
        resMap.put("success",true);
        return resMap;
    }

    public Map<String,Object> getApplicationCoreList(List<ApplicationCore> acList,int page,int total){
        Map<String,Object> resMap = new HashMap<String,Object>();
        List<Map<String,Object>> rowsList = new ArrayList<>();
        for(ApplicationCore ac : acList){
            Map<String,Object> tempMap = new HashMap<>();
            tempMap.put("ApplicationCore",ac);
            int currentAllCounts = airm.selectCountByApplicationCoreIdAndStatus(ac.getApplicationCoreId(),null);
            tempMap.put("runningCounts",currentAllCounts);
            rowsList.add(tempMap);
        }
        resMap.put("page",page);
        resMap.put("records",total);
        resMap.put("rows",rowsList);
        resMap.put("success",true);
        return  resMap;
    }

    public Map<String,Object> getApplicationListByUsername(ParamsApplication paramsApplication,int page,int rows){
        Map<String,Object> resMap = new HashMap<String,Object>();
        int total = acm.selectCountByLittleFields(paramsApplication.applicationCore);
        List<ApplicationCore> acList;
        acList = acm.selectByLittleFields(paramsApplication.applicationCore,(page-1)*rows,rows);
        return this.getApplicationCoreList(acList,page,total);
    }

    public Map<String,Object> getApplicationListByMultipleFields(ParamsApplication paramsApplication,int page,int rows){
        Map<String,Object> resMap = new HashMap<String,Object>();
        int total = acm.selectCountByMoreFields(paramsApplication.applicationCore);
        List<ApplicationCore> acList;
        acList = acm.selectByMoreFields(paramsApplication.applicationCore,(page-1)*rows,rows);
        List<Map<String,Object>> rowsList = new ArrayList<>();
        return this.getApplicationCoreList(acList,page,total);
    }

    private ParamsApplication copyPa(ParamsApplication paramsApplication,String imageNameTag){
        ParamsApplication pa= new ParamsApplication();
        pa.applicationCore = new ApplicationCore();
        pa.applicationCore.setApplicationCoreId(paramsApplication.applicationCore.getApplicationCoreId());
        pa.imageNameTag = imageNameTag;
        return pa;
    }

    public ParamsApplication getOldParamsConversion(ParamsApplication paramsApplication,ParamsDeployerConversion pdc){
        ParamsApplication pa = this.copyPa(paramsApplication,pdc.oldVersion);
        paramsApplication.imageNameTag = pdc.oldVersion;
        pa.ip = paramsApplication.ip;
        List<ApplicationInstanceRelation> airList = airm.selectByApplicationCoreId(pa.applicationCore.getApplicationCoreId());
        airList = this.filterAirListByImageNameTag(airList,pa);
        System.out.println(airList.size());
        if(pdc.conversionType.equals("number") && airList.size()>airList.size()-pdc.number && airList.size()-pdc.number>0){
            System.out.println("getOldCompactionNum"+pdc.getOldCompactionNum());
            pa.instanceReplica = airList.size()-pdc.number ;
            return pa;
        }
        else if(pdc.conversionType.equals("scale") && pdc.factor<=1 && pdc.factor>0){
            pa.instanceReplica = airList.size() - (int) ((Integer)airList.size()* pdc.factor);
            pa.needDoneNum = (int) ((Integer)airList.size()* pdc.factor);
            return pa;
        }
        return null;
    }

    public ParamsApplication getCurrentParamsConversion(ParamsApplication paramsApplication,ParamsDeployerConversion pdc,int count){
        ParamsApplication pa = this.copyPa(paramsApplication,pdc.currentVersion);
        paramsApplication.imageNameTag = pdc.currentVersion;
        List<ApplicationInstanceRelation> airList = airm.selectByApplicationCoreId(pa.applicationCore.getApplicationCoreId());
        airList = this.filterAirListByImageNameTag(airList,pa);
        System.out.println(airList.size());
        pa.ip = paramsApplication.ip;
        if(pdc.conversionType.equals("number") && airList.size()<airList.size()+pdc.number && airList.size()+pdc.number>1){
            System.out.println("getCurrentExpansionNum"+pdc.getCurrentExpansionNum());
            pa.instanceReplica = airList.size()+pdc.number;
            return pa;
        }
        else if(pdc.conversionType.equals("scale") && pdc.factor<=1 && pdc.factor>0){
            pa.instanceReplica = airList.size()+count;
            return pa;
        }
        return null;
    }

    public ApplicationCore getApplicationCoreById(Integer applicationCoreId){
        return acm.selectByPrimaryKey(applicationCoreId);
    }

    public Map<String,Object> getApplicationImageVersion(Integer applicationCoreId,int page,int rows){
        Map<String,Object> resMap = new HashMap<>();
        List<ApplicationInstanceRelation> airList = airm.selectDistinctImageIdByApplicationCoreId(applicationCoreId,(page-1)*rows,rows);
        resMap.put("records",airm.selectDistinctImageCountIdByApplicationCoreId(applicationCoreId));
        List<InstanceImage>  iiList = new ArrayList<>();
        for(int i = 0;i<airList.size();i++){
            ApplicationInstanceRelation air = airList.get(i);
            InstanceImage ii = iim.selectByPrimaryKey(air.getImageId());
            iiList.add(ii);
        }
        resMap.put("rows",iiList);
        resMap.put("success",true);

        return  resMap;
    }

    public static void main(String[] args) {
        DbService db = new DbService();
        System.out.println(db.checkSptringSpliterMatch("1","1"));
    }

    public List<ParamsApplication> getAllAir(Integer appliationCoreId){
        List<ParamsApplication> resList = new ArrayList<>();
        List<ApplicationInstanceRelation> airList = this.airm.selectByApplicationCoreId(appliationCoreId);
        if(airList !=null && airList.size() >0){
            for(ApplicationInstanceRelation air :airList){
                ParamsApplication pa = new ParamsApplication();
                pa.air = air;
                pa.applicationCore = acm.selectByPrimaryKey(appliationCoreId);
                resList.add(pa);
            }
        }
        return resList;
    }

    public ApplicationCore deleteApplicationCore(Integer applicationCoreId){
        ApplicationCore ac = this.acm.selectByPrimaryKey(applicationCoreId);
        if(ac !=null){
            ac.setApplicationCoreDeleteDatetime(new Date());
            acm.updateByPrimaryKeySelective(ac);
            return ac;
        }
        return null;
    }

    public Map getApplicationStatisticalInfo(ParamsApplication pa){
        Map<String,Object> resMap = new HashMap<>();
        resMap.put("runningApplicationCounts",this.acm.selectRunningCountByMoreFields(pa.applicationCore));
        resMap.put("applicationCounts",this.acm.selectCountByMoreFields(pa.applicationCore));
        resMap.put("last5UpdateTime",this.getApplicationNotNullFields(this.acm.selectByUpdate(pa.applicationCore,0,5)));
        resMap.put("last5ImageCount",this.getApplicationNotNullFields(acm.selectByImageCount(pa.applicationCore,0,5)));
        resMap.put("success",true);
        return resMap;
    }

    private List<Map<String,Object>> getApplicationNotNullFields(List<ApplicationCore> acList){
        List<Map<String,Object>> resList = new ArrayList<>();
        for(ApplicationCore ac : acList){
            Map<String,Object> tempMap = new HashMap<>();
            tempMap.put("applicationCoreId",ac.getApplicationCoreId());
            tempMap.put("applicationCoreUpdateDatetime",UsefulTools.utilDateConverter(ac.getApplicationCoreUpdateDatetime()));
            tempMap.put("applicationCoreImagesCounts",ac.getApplicationCoreImagesCounts());
            tempMap.put("applicationCoreRename",ac.getApplicationCoreRename());
            resList.add(tempMap);
        }
        return resList;
    }

    public void updateApplicationImageCount(ParamsApplication paramsApplication){
        paramsApplication.applicationCore = acm.selectByPrimaryKey(paramsApplication.applicationCore.getApplicationCoreId());
        if(paramsApplication.applicationCore.getApplicationCoreImagesCounts() == null){
            paramsApplication.applicationCore.setApplicationCoreImagesCounts(1);
        }
        else{
            paramsApplication.applicationCore.setApplicationCoreImagesCounts(paramsApplication.applicationCore.getApplicationCoreImagesCounts()+1);
        }
        this.getAcm().updateByPrimaryKeySelective(paramsApplication.applicationCore);
    }
}
